package com.by.controller;


import cn.hutool.core.bean.BeanUtil;
import com.by.auth.TokenTemplate;
import com.by.bean.LoginBean;
import com.by.bean.User;
import com.by.common.bean.PageBean;
import com.by.common.bean.ResultBean;
import com.by.common.controller.BaseController;
import com.by.common.query.UserQuery;
import com.by.mapper.UserMapper;
import com.by.service.UserService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 使用 @Api 注解来标记当前类或接口，
 * 指定一组相关的 API 资源标签（tags），便于在生成的文档中分类显示
 *
 * @author yqs
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/v1")
public class UserController extends BaseController {
    @Autowired
    UserService userService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    TokenTemplate tokenTemplate;

    /**
     * 执行账号唯一性检查的API控制器方法。
     * <p>
     * 该方法接收一个 HTTP GET 请求，并通过查询数据库来判断指定账号是否已被注册使用。
     * 如果账号存在，则返回提示信息表示该账号不可用；否则，返回提示信息表示账号可用。
     *
     * @param account 待检查的账号名称
     * @return 包含检查结果的消息对象
     */
    @ApiImplicitParam(name = "account", paramType = "query", value = "账号", dataTypeClass = String.class, required = true)
    @ApiOperation("账号唯一检查")
    @GetMapping("/user/check")
    public ResultBean checkUser(
            @RequestParam(name = "account", required = true) String account
    ) {
        // 查询指定账号是否存在
        int rs = userService.queryUserByAccount(account);

        // 根据查询结果构建响应消息
        String tmp = rs == 1 ? "账号已存在不可用" : "此账号可用";

        // 返回封装好的检查结果
        return success("账号唯一检查", tmp);
    }

    @ApiOperation("用户列表")
    @PostMapping("/user/query")
    public ResultBean query(@RequestBody UserQuery query) {
        Map<String, Object> map = BeanUtil.beanToMap(query);
        PageBean bean = userService.query(map);
        return success("用户列表", bean);
    }

    @ApiOperation(value = "删除用户")
    @DeleteMapping("/user")
    public ResultBean delete(@ApiParam(name = "id", value = "要删除的用户id") @RequestParam(name = "id", required = true, defaultValue = "0") int id) {
        int rs = userService.delete(id);
        return deleteResult(rs);
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",
                    value = "用户id",
                    dataTypeClass = Integer.class,
                    required = true,
                    paramType = "query"),
            @ApiImplicitParam(name = "status",
                    value = "用户状态0 禁用 1 启用",
                    dataTypeClass = Integer.class,
                    required = true,
                    paramType = "query")
    })
    @ApiOperation("修改状态")
    @PutMapping("/user/status")
    public ResultBean updateStatus(@RequestParam(name = "id", required = true, defaultValue = "0") int id,
                                   @RequestParam(name = "status", required = true, defaultValue = "0") int status) {
        int rs = userService.updateStatus(id, status);
        return updateResult(rs);
    }

    /**
     * 用户登录接口
     *
     * @param loginBean 登录参数对象，包含账号和密码
     * @param result    表单验证结果对象，用于捕获验证错误
     * @return 返回登录结果，包括成功或失败的信息以及用户信息
     */
    @ApiOperation("用户登录")
    @PostMapping("/user/login")
    public ResultBean login(@Validated @RequestBody LoginBean loginBean, BindingResult result) {
        // 验证登录参数的合法性
        validate(result);
        // 根据账号查询用户信息
        User user = userService.queryByAccount(loginBean.getAccount());
        // 判断用户是否存在
        if (null == user) {
            return fail("该账号不存在");
        }
        // 计算密码的MD5值
        String pwd = DigestUtils.md5DigestAsHex(loginBean.getPassword().getBytes());
        // 验证密码是否正确
        if (!pwd.equals(user.getPassword())) {
            return fail("账号或密码不正确");
        }
        // 检查用户状态是否禁用
        if (user.getStatus() == 1) {
            return fail("该账号已禁用,请联系管理员");
        }
        // 将User转换成Map
        Map map = BeanUtil.beanToMap(user);
        // 初始化角色列表
        List<String> roleList = new ArrayList<>();
        // 如果用户有身份标识，则添加到角色列表中
        if (null != user.getIdentification() && !"".equals(user.getIdentification())) {
            roleList.add(user.getIdentification());
        }
        // 将角色列表添加到用户信息Map中
        map.put("roles", roleList);
        // 移除密码信息，以确保安全性
        map.remove("password");
        // 生成token，用于后续的身份验证
        String token = tokenTemplate.generateToken(map);
        // 将token添加到用户信息Map中
        map.put("accessToken", token);

        // 返回登录成功的结果，包含用户信息和token
        return success("登录成功", map);
    }

}


//public class UserController extends BaseController {
//
//    @Autowired
//    UserService userService;
//    @Autowired
//    HttpServletRequest request;
//
//    /**
//     * 使用 @ApiOperation 注解来标记一个具体的方法，描述该方法的功能和用途
//     * 添加新用户的方法。
//     * 此方法接收来自客户端的POST请求，并期望在请求体中包含符合{@link User}模型的有效数据。
//     * 在添加前会对输入的数据进行校验，若发现任何违反约束的情况，则会返回相应的错误信息。
//     * 若无误则调用业务层保存用户并根据操作结果构建响应。
//     *
//     * @param user   经过验证后的用户实体对象。
//     * @param result 从表单绑定过程中收集的所有错误信息。
//     * @return 根据保存操作的结果返回对应的ResultBean实例。
//     */
//    @ApiOperation(value = "添加用户")
//    @PostMapping("/user")
//    public ResultBean save(@Validated({ISave.class}) @RequestBody User user, BindingResult result) {
//        //
//        validate(result);
//
//        int rs = userService.save(user);
//        return saveResult(rs);
//    }
//
//    /**
//     * 更新用户信息的方法。
//     * <p>
//     * 此方法负责接收经过验证的用户对象，并处理可能存在的表单验证错误。
//     * 通过 {@link IUpdate} 分组约束确保只有在更新操作中需要检查的字段被验证。
//     * 如果有验证错误发生，则通过调用 `validate` 方法收集所有字段错误并抛出自定义异常；
//     * 否则，将尝试通过 {@link UserService} 更新用户数据，并基于更新结果构建合适的响应。
//     *
//     * @param user   经过验证后的用户实体对象，包含用户的详细信息。
//     * @param result BindingResult 参数用于捕获和处理表单提交时发生的任何验证异常。
//     * @return 根据更新操作的结果生成对应的 ResultBean 实例。
//     */
//    @ApiOperation(value = "更新用户信息")
//    @PutMapping("/user")
//    public ResultBean update(@Validated({IUpdate.class}) @RequestBody User user, BindingResult result) {
//        validate(result);
//        int rs = userService.update(user);
//        return updateResult(rs);
//    }
//
//    /**
//     * 使用 @ApiImplicitParam 注解来描述一个 HTTP 请求中的参数。
//     * 此处指定了名称为 "id" 的参数，并提供了关于该参数的说明信息。
//     * 参数 "required = true" 表示该参数是必需的，即客户端在调用此接口时必须提供该参数。
//     * 参数 "defaultValue = '0'" 提供了一个默认值，如果客户端未明确提供该参数，则使用此默认值。
//     * 参数 "dataTypeClass = Integer.class" 指定了该参数的数据类型为整型（Integer）。
//     */
//    @ApiImplicitParam(name = "id", value = "用户id", required = true, defaultValue = "0", dataTypeClass = Integer.class)
//    /**
//     * 使用 @ApiOperation 注解来标记一个具体的方法，描述该方法的功能和用途，
//     * 这里指明了该方法用于“根据 id 删除用户信息”
//     */
//
//    @ApiOperation(value = "根据id删除用户信息")
//    @DeleteMapping("/user")
//    public ResultBean delete(@ApiParam(name = "id", value = "要删除的用户id") @RequestParam(name = "id", required = true, defaultValue = "0") int id) {
//
//        int rs = userService.delete(id);
//        return deleteResult(rs);
//    }
//
//    @ApiOperation(value = "分页查询用户信息")
//    /**
//     * 使用 @ApiImplicitParams 注解来描述一组 HTTP 请求中的参数。
//     * 通过此注解可以指定多个参数的信息，并提供详细的描述。
//     *
//     * 第一个参数：
//     * - name = "page"：表示参数名称为 "page"；
//     * - value = "当前是第几页"：提供关于该参数的详细描述；
//     * - dataTypeClass = Integer.class：指定参数的数据类型为整型（Integer）；
//     * - required = true：表示该参数是必需的，客户端在调用此接口时必须提供该参数。
//     *
//     * 第二个参数：
//     * - name = "pageSize"：表示参数名称为 "pageSize"；
//     * - value = "每页有几条数据"：提供关于该参数的详细描述；
//     * - dataTypeClass = Integer.class：指定参数的数据类型为整型（Integer）；
//     * - required = true：表示该参数是必需的，客户端在调用此接口时必须提供该参数。
//     */
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "page",
//                    value = "当前是第几页",
//                    dataTypeClass = Integer.class,
//                    required = true,
//                    paramType = "query"),
//            @ApiImplicitParam(name = "pageSize",
//                    value = "每页有几条数据",
//                    dataTypeClass = Integer.class,
//                    required = true,
//                    paramType = "query")
//    })
//    @GetMapping("/user")
//// 使用@GetMapping注解指定此方法处理HTTP GET请求，并且路径为/user
//
//    public ResultBean<PageBean> query(
//            @ApiIgnore // 标记此参数不被Swagger等API文档工具记录
//            @RequestParam Map map // 接收一个Map类型的参数，用于查询条件传递
//    ) {
//
//        DispatcherServlet dispatcherServlet;
//        // 声明一个DispatcherServlet变量，但未实际使用
//
//        String path = request.getServletContext().getRealPath("/");
//        // 获取当前项目的绝对路径并存储在path变量中
//
//        System.out.println(path);
//        // 打印项目路径到控制台以便调试或日志记录
//
//        PageBean bean = userService.query(map);
//        // 调用userService对象的query方法执行具体的业务逻辑，并传入map作为查询参数
//
//        return success("用户列表", bean);
//        // 返回一个ResultBean实例封装的结果数据，其中包含操作成功的信息及返回的数据bean
//    }
//}
